//
//  组合模式通用代码.swift
//  GroupPattern
//
//  Created by mac on 2017/11/16.
//  Copyright © 2017年 RRC. All rights reserved.
//

import Foundation

//抽象构件角色
public class Component{
    /**
     定义参加组合对象的共有方法和属性，可以定义一些默认的行为或属性；
     */
    
    //个体和整体都具有的共享
    func doSomething(){
        //编写业务逻辑
        
    }
    
}

//树枝构件：树枝对象，它的作用是组合树枝节点和叶子节点形成一个树形结构。
public class Composite:Component{
    //构件容器
    private var componentList = [Component]()
    
    //增加一个叶子构件或树枝构件
    func add(component:Component){
        self.componentList.append(component)
    }
    
    //删除一个叶子构件或树枝构件
    func remove(component:Component){
        let array:NSMutableArray = self.componentList as! NSMutableArray
        array .remove(component)
        self.componentList = array as! Array
    }
    
    //获得分支下的所能叶子构件和树枝构件
    func getChildren() -> [Component] {
        return self.componentList
    }
}

//叶子构件：叶子对象，其下再也没有其他的分支，也就是遍历的最小单位
public class TYLeaf:Component {
    
    /*
    //可以重写父类方法
    override func doSomething() {
        
    }
    */
}

public class Client{
    public func main(srgs:[String]){
        //创建一个根节点
        let root = Composite()
        root.doSomething()
        //创建一个树枝构件
        let branch = Composite()
        //创建一个叶子节点
        let leaf = TYLeaf()
        //建立整体
        root.add(component: branch)
        branch.add(component: leaf)
    }
}

//通过递归遍历树
public func display(root:Composite){
    for obj in root.getChildren() {
        if obj is TYLeaf{
            obj.doSomething()
        }else{
            display(root: obj as! Composite)
        }
    }
}

/**
 组合模式的优点：
    1､高层模块调用简单
    2､节点自由增加
缺点：
    在面向接口编程上是很不恰当的，与依赖倒置原则冲突，它限制了接口的影响范围
使用场景：
    1､维护和展示部分-整体关系的场景，如树形菜单、文件和文件管理
    2､从一个整体中能够独立出部分模块或功能的场景；
 */


